<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>1、构造函数和原型</title>
</head>
<body>
    <script>
        /**
         * 实例化成员&静态成员
         * */
        var initFn = (function(){
            // 构造函数中的属性和方法称为成员，成员可以添加
            function Star(name, age){
                this.uname = name;
                this.age = age;
                this.sing = function(){
                    console.log('我爱唱歌');
                }
            }

            var ldh = new Star('刘德华', 18);
            console.log(ldh);

            // 实例成员就是构造函数内部通过thiss添加的成员 uname age sing就是实例成员
            // 实例成员只能通过实例化对象来访问

            console.log(ldh.uname); // 刘德华
            // console.log(Star.uname); // undefined

            // 静态成员 在构造函数上添加的成员
            Star.sex = '男';
            // 静态成员只能通过构造函数来访问
            console.log(Star.sex); // 男
            // console.log(ldh.sex); // undefined
        });

        var initFn2 = (function(){
            // 构造函数的问题：存在浪费内存的问题
            // 解决：构造函数的原型对象prototype，实现共享
            function Star(name, age){
                this.uname = name;
                this.age = age;
            }

            // var ldh = new Star('刘德华', 18);

            // 我们可以把那些不变的方法，直接定义在prototype对象上，这样就可以共享这些方法

            // Star.prototype.sing = function(){
            //     console.log('我爱唱歌');
            // }
            // ldh.sing();
            // 原型的作用：共享方法

            // 对象都会有一个属性__proto__指向构造函数的prototype原型对象
            // __proto__和prototype是等价的
            // constructor构造函数
            // __proto__和prototype都有一个constructor属性，它指向构造函数本身
            // constructor主要用于记录该对象引用于哪个构造函数

            Star.prototype = {
                sing:function(){
                    console.log('我爱唱歌');
                },
                moive: function(){
                    console.log('我爱演电影');
                },
                constructor: Star
            }
            var ldh = new Star('刘德华', 18);

            ldh.sing();
        });

        // 原型链
        var initFn3 = (function(){
            function Star(name, age){
                this.uname = name;
                this.age = age;
            }
            Star.prototype = {
                sing:function(){
                    console.log('我爱唱歌');
                },
                constructor: Star
            }

            var ldh = new Star();
            console.log(Star.prototype);

            // 原型链：
            //            __proto__               __proto__                 __proto__
            // ldh对象实例    =>    Star.prototype    =>    Object.prototype    =>    null
        });

        // 类的本质
        var initFn4 = (function(){
            // 类的本质：函数(function)
            class Star{}
            console.log(typeof Star);
            // 类其实就是语法糖
            // es5新增方法 forEach map filter some every
            var arr = [1, 2, 3];
            // arr.forEach(function(value, index, array){
            //     console.log('每个数组元素:'+ value);
            //     console.log('每个数组位置:'+ index);
            //     console.log('数组本身:'+ array);
            // })
            
            // 返回新数组
            // var newArr = arr.filter((value, index) => {
            //     return value > 1;
            // });
            
            // 返回布尔值
            var bool = arr.some((value, index) => {
                return value > 1;
            });

            console.log(bool);
        });

        initFn();
        console.log('-----分割线-----');
        initFn2();
        console.log('-----分割线-----');
        initFn3();
        console.log('-----分割线-----');
        initFn4();
    </script>
</body>
</html>